package lampsServer;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.DefaultListModel;
import javax.swing.table.DefaultTableModel;

import bean.ClientBean;
import bean.ServerBean;

public class LampsServer {
	//默认列表，用户信息存储
	DefaultListModel<Object> myListmodel =new DefaultListModel<>();
	//路灯控制界面
	private static ServerView serverView =null;
	//服务器套接字
	private static ServerSocket serverSocket;
	//哈希表存储已连接服务器的路灯对象的套接字
	public static HashMap<String, Socket> clientSockets;
	//实例化一个空表格
	static DefaultTableModel defaultTableModel = new DefaultTableModel();
	//表中列元素
	static Vector<String> column =new Vector<>();

	//静态初始化块，类加载时调用
	static {
		try {
			//服务器端口号为8520
			serverSocket = new ServerSocket(8520);

			clientSockets = new HashMap<String, Socket>();
			//添加一列"路灯id"
			defaultTableModel.addColumn("路灯id");
			//添加一列"温度"
			defaultTableModel.addColumn("温度");
			//添加一列"湿度"
			defaultTableModel.addColumn("湿度");
			//添加一列"环境照度"
			defaultTableModel.addColumn("环境照度");
			//添加一列"路灯状态"
			defaultTableModel.addColumn("路灯状态");
			//表头
			Object[] data =new Object[5];
			//表头赋值
			data[0]=("路灯id");
			data[1]=("温度");
			data[2]=("湿度");
			data[3]=("环境照度");
			data[4]=("路灯状态");
			//表头加入表格
			defaultTableModel.addRow(data);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//客户端请求处理
	class ClientThread extends Thread {
		//客户端套接字
		private Socket clientSocket;
		//从客户端接收到的ClientBean对象
		private ClientBean clientBean;
		//对象输入流
		private ObjectInputStream ois;
		//对象输出流
		private ObjectOutputStream oos;

		//构造函数，参数为服务器接收到的客户端套接字
		public ClientThread(Socket clientSocket) {
			this.clientSocket = clientSocket;
		}

		@Override
		public void run() {
			try {
				//不停的从客户端接收信息
				while (true) {
					//读取从客户端接收到的ClientBean信息
					ois = new ObjectInputStream(clientSocket.getInputStream());
					clientBean = (ClientBean) ois.readObject();
					//分析ClientBean中，type是那样一种类型
					switch (clientBean.getType()) {
					//请求连接
					case 0: {
						//将各路灯对应的Socket存下来
						clientSockets.put(clientBean.getLightId(), clientSocket);

						new Thread(){
							@SuppressWarnings("unchecked")
							public void run() {
								//将接收到的用户加入列表
								myListmodel.addElement(clientBean.getLightId());
								//新建一个储存服务器表中路灯信息的对象
								Object[] data =new Object[5];
								//对象赋值
								data[0]=(clientBean.getLightId());
								data[1]=(clientBean.getTem());
								data[2]=(clientBean.getHum());
								data[3]=(clientBean.getLight());
								if(clientBean.getState())
									data[4]=("打开");
								else
									data[4]=("关闭");
								//将当前路灯对象的信息添加入表
								defaultTableModel.addRow(data);
								//刷新列表
								serverView.list.setModel(myListmodel);
								//刷新表格
								serverView.table.setModel(defaultTableModel);
							};
						}.start();
						break;
					}
					//路灯对象请求断开连接
					case -1: {
						//创建服务器的serverBean，并发送给客户端
						ServerBean serverBean = new ServerBean();
						//给予该客户端断开连接命令
						serverBean.setType(-1);
						//将该指令送给该客户端
						try {
							oos = new ObjectOutputStream(clientSocket.getOutputStream());
							oos.writeObject(serverBean);
							oos.flush();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						new Thread(){
							@SuppressWarnings("unchecked")
							public void run() {
								//遍历表格，将该路灯对象的信息移除
								for(int i = 0;i<defaultTableModel.getRowCount();i++){
									if(defaultTableModel.getValueAt(i,0).equals(clientBean.getLightId())){
										defaultTableModel.removeRow(i);
									}
								}
								//将该对象从列表中删除
								myListmodel.removeElement(clientBean.getLightId());
								//刷新列表
								serverView.list.setModel(myListmodel);
							};
						}.start();
						return;
					}
					//上传数据
					case 1: {
						new Thread(){
							public void run() {
								//遍历表格，将当前路灯对象的旧数据移除
								for(int i = 0;i<defaultTableModel.getRowCount();i++){
									if(defaultTableModel.getValueAt(i,0).equals(clientBean.getLightId())){
										defaultTableModel.removeRow(i);
									}
								}
								//新建一个储存服务器表中路灯信息的对象
								Object[] data =new Object[5];
								//对象赋值
								data[0]=(clientBean.getLightId());
								data[1]=(clientBean.getTem());
								data[2]=(clientBean.getHum());
								data[3]=(clientBean.getLight());
								if(clientBean.getState())
									data[4]=("打开");
								else
									data[4]=("关闭");
								//将新数据添加入表
								defaultTableModel.addRow(data);
							};
						}.start();
						break;
					}
					default: {
						break;
					}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} finally {
				//关闭各接口
				close();
			}
		}

		//关闭各接口
		private void close() {
			if (oos != null) {
				try {
					oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ois != null) {
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (clientSocket != null) {
				try {
					clientSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	//服务器入口函数
	public void start() {
		try {
			//一直侦听
			while (true) {
				//侦听并接受到serverSocket这个套接字的连接
				Socket clientSocket = serverSocket.accept();
				//接收客户端请求并处理
				new ClientThread(clientSocket).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		serverView = new ServerView();
		serverView.setVisible(true);
		//显示路灯详细信息表格的表头
		serverView.table.setModel(defaultTableModel);

		//通过系统默认构造函数创建一个路灯服务器对象
		LampsServer lampsServer =new LampsServer();
		//打开服务器
		lampsServer.start();
		//将当前lampsServer传给控制面板，以便其下发命令
		serverView.setCatServer(lampsServer);
	}

}